package net.xdclass.controller;

import lombok.extern.slf4j.Slf4j;
import net.xdclass.enums.ShortLinkStateEnum;
import net.xdclass.service.LogService;
import net.xdclass.service.ShortLinkService;
import net.xdclass.service.impl.LogServiceImpl;
import net.xdclass.util.CommonUtil;
import net.xdclass.vo.ShortLinkVO;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * @Classname LinkApiController
 * @Description 客户端
 * @Date 2023-04-27 22:13
 * @Created by lihw
 */
@Controller
@Slf4j
public class LinkApiController {

    @Autowired
    private ShortLinkService shortLinkService;

    @Autowired
    private LogService logService;

    @GetMapping(path = "/{shortLinkCode}")
    public void dispatch(@PathVariable("shortLinkCode") String shortLinkCode,
                         HttpServletRequest request,
                         HttpServletResponse response) {
      log.info("短链码：{}", shortLinkCode);
      //判断短链码是否合规
        try {
            if(isLetterDigit(shortLinkCode)) {
                // 查找短链 TODO
                ShortLinkVO shortLinkVO = shortLinkService.parseShortLinkCode(shortLinkCode);

                if (StringUtils.isNotBlank(shortLinkCode)) {
                    logService.recordShortLinkLog(request, shortLinkCode, shortLinkVO.getAccountNo());
                }

                // 判断是否过期和可用
                if(isVisitable(shortLinkVO)) {
                    String originalUrl = CommonUtil.removeUrlPrefix(shortLinkVO.getOriginalUrl());
                    response.setHeader("Location", originalUrl);
                    // 302 跳转
                    response.setStatus(HttpStatus.FOUND.value());
                } else {
                    //不可用 404
                    response.setStatus(HttpStatus.NOT_FOUND.value());
                }
            }

        } catch (Exception e) {
            response.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());
        }
    }

    /**
     * 判断短链是否可用
     * @param shortLinkVO
     * @return
     */
    private static boolean isVisitable(ShortLinkVO shortLinkVO){
        // 检查是否过期
        if(shortLinkVO != null && shortLinkVO.getExpired().getTime() > CommonUtil.getCurrentTimestamp()) {
            // 检查手可用
            if(ShortLinkStateEnum.ACTIVE.name().equalsIgnoreCase(shortLinkVO.getState())) {
                return true;
            }
        } else if (shortLinkVO != null && shortLinkVO.getExpired().getTime() == -1) {
            if(ShortLinkStateEnum.ACTIVE.name().equalsIgnoreCase(shortLinkVO.getState())) {
                return true;
            }
        }
        return false;
    }

    /**
     * 仅包括数字和字母
     * @param str
     * @return
     */
    private static boolean isLetterDigit(String str){
        String regx = "^[a-z0-9A-Z]+$";
        return str.matches(regx);
    }
}
